import os
import cv2
from PIL import Image
import win32gui
from PySide6.QtCore import Qt, QPoint
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import  QWidget, QHBoxLayout, QVBoxLayout, QGridLayout
from qfluentwidgets import SingleDirectionScrollArea, SimpleCardWidget, CaptionLabel, LineEdit, ComboBox, PushButton, CheckBox
from core.screenshot import hwnd_title, get_all_hwnd, get_screenshot_image, get_mss_screenshot_image
from core.mhcoord import decode_loc, draw_map, draw_map_prec
from core.util import time_str, delete_file
from core.maocr import maocr
from core.log import logger
import setting as c
import core.model_signin as u
from gui.common_gui import GUI_CARD
from gui.gui_developmode import SFormDevelopMode

class CustomLineEdit(LineEdit):
    def __init__(self, parent=None):
        super(CustomLineEdit, self).__init__(parent)

    def focusInEvent(self, event):
        # 在 CustomLineEdit 获得焦点时调用
        super().focusInEvent(event)
        # 控件获得焦点时全选文本
        self.clear()

class CoordInfoCard(SimpleCardWidget):
    """ App information card """

    def __init__(self, parent=None):
        super().__init__(parent)
        self.father = parent
        self.card = GUI_CARD.COORD
        self.sf_developmode = SFormDevelopMode(self, "坐标截图校准", self.card, 0)
        self.sf_developmode.setModal(True)
        
        self.alert_lb = CaptionLabel()
        self.alert_lb.setText(c.TIPS_COORD_ALERT)
       
        self.win_combo = ComboBox()
        self.update_win_combo()
        self.recognize_btn = PushButton('RE')
        self.recognize_btn.clicked.connect(self.onclick_recogize)
        
        self.loc_btn = []
        self.cs_btn = PushButton('长寿')
        self.cs_btn.clicked.connect(lambda: self.onclick_loc("cs"))
        self.loc_btn.append(self.cs_btn)
        
        self.bx_btn = PushButton('宝象')
        self.bx_btn.clicked.connect(lambda: self.onclick_loc("bx"))
        self.loc_btn.append(self.bx_btn)
        
        self.xl_btn = PushButton('西梁女国')
        self.xl_btn.clicked.connect(lambda: self.onclick_loc("xl"))
        self.loc_btn.append(self.xl_btn)
        
        self.jw_btn = PushButton('境外')
        self.jw_btn.clicked.connect(lambda: self.onclick_loc("jw"))
        self.loc_btn.append(self.jw_btn)
        
        self.al_btn = PushButton(f"傲来")
        self.al_btn.clicked.connect(lambda: self.onclick_loc("al"))
        self.loc_btn.append(self.al_btn)
        
        self.ne_btn = PushButton('女儿村')
        self.ne_btn.clicked.connect(lambda: self.onclick_loc("ne"))
        self.loc_btn.append(self.ne_btn)
        
        self.jy_btn = PushButton('建邺')
        self.jy_btn.clicked.connect(lambda: self.onclick_loc("jy"))
        self.loc_btn.append(self.jy_btn)
        
        self.jnyw_btn = PushButton('野外')
        self.jnyw_btn.clicked.connect(lambda: self.onclick_loc("jnyw"))
        self.loc_btn.append(self.jnyw_btn)
        
        self.zz_btn = PushButton('朱紫')
        self.zz_btn.clicked.connect(lambda: self.onclick_loc("zz"))
        self.loc_btn.append(self.zz_btn)
        
        self.pt_btn = PushButton('普陀山')
        self.pt_btn.clicked.connect(lambda: self.onclick_loc("pt"))
        self.loc_btn.append(self.pt_btn)
        
        self.wz_btn = PushButton('五庄观')
        self.wz_btn.clicked.connect(lambda: self.onclick_loc("wz"))
        self.loc_btn.append(self.wz_btn)
        
        self.gj_btn = PushButton('国境')
        self.gj_btn.clicked.connect(lambda: self.onclick_loc("gj"))
        self.loc_btn.append(self.gj_btn)
        
        
        self.loc_le = CustomLineEdit()
        self.loc_le.setPlaceholderText("al 12 34")
        self.loc_le.returnPressed.connect(lambda: self.on_return_loc_le(self.loc_le.text()))
        self.gen_btn = PushButton('GEN')
        self.gen_btn.clicked.connect(lambda: self.on_return_loc_le(self.loc_le.text()))

        self.loc_ocr_le = LineEdit()
        self.loc_ocr_le.setPlaceholderText("auto ocr")
        self.loc_ocr_le.returnPressed.connect(lambda: self.on_return_loc_le(self.loc_ocr_le.text(), True))
        self.gen_ocr_btn = PushButton('GEN')
        self.gen_ocr_btn.clicked.connect(lambda: self.on_return_loc_le(self.loc_ocr_le.text(), True))
        
        self.map_label = CaptionLabel()
        
        self.prec_cb = CheckBox('抓鬼预测(仅供参考)')
        self.prec_cb.setChecked(True)
        self.tips_label = CaptionLabel('')
        self.setTips(c.TIPS_OCR)

        self.vBoxLayout = QVBoxLayout(self)
        self.hBoxLayout_alert = QHBoxLayout()
        self.hBoxLayout_re = QHBoxLayout()
        self.hBoxLayout_gen = QHBoxLayout()
        self.hBoxLayout_ocr_gen = QHBoxLayout()
        self.gridLayout_loc = QGridLayout()
        
        self.hBoxLayout_map = QHBoxLayout()
        self.hBoxLayout_tips = QHBoxLayout()
        
        self.initLayout()

    def initLayout(self):
        self.hBoxLayout_alert.setSpacing(10)
        self.hBoxLayout_alert.setContentsMargins(5, 5, 3, 3)
        self.hBoxLayout_alert.addWidget(self.alert_lb, 4)
        
        self.hBoxLayout_re.setSpacing(10)
        self.hBoxLayout_re.setContentsMargins(5, 5, 3, 3)
        self.hBoxLayout_re.addWidget(self.win_combo, 4)
        self.hBoxLayout_re.addWidget(self.recognize_btn, 1)
        
        self.hBoxLayout_ocr_gen.setSpacing(10)
        self.hBoxLayout_ocr_gen.setContentsMargins(5, 5, 3, 3)
        self.hBoxLayout_ocr_gen.addWidget(self.loc_ocr_le, 4)
        self.hBoxLayout_ocr_gen.addWidget(self.gen_ocr_btn, 1)
        
        self.hBoxLayout_gen.setSpacing(10)
        self.hBoxLayout_gen.setContentsMargins(5, 5, 3, 3)
        self.hBoxLayout_gen.addWidget(self.loc_le, 4)
        self.hBoxLayout_gen.addWidget(self.gen_btn, 1)
        
        positions = [(i, j) for i in range(4) for j in range(4)]
        for i in range(len(self.loc_btn)):
            self.gridLayout_loc.addWidget(self.loc_btn[i], *positions[i])
            
        
        self.hBoxLayout_map.setSpacing(10)
        self.hBoxLayout_map.setContentsMargins(5, 5, 3, 3)
        self.hBoxLayout_map.addWidget(self.map_label)
        
        self.hBoxLayout_tips.setSpacing(10)
        self.hBoxLayout_tips.setContentsMargins(5, 5, 3, 3)
        self.hBoxLayout_tips.addWidget(self.prec_cb)
        self.hBoxLayout_tips.addWidget(self.tips_label)
        
        self.vBoxLayout.addLayout(self.hBoxLayout_alert)
        self.vBoxLayout.addLayout(self.hBoxLayout_re)
        self.vBoxLayout.addLayout(self.hBoxLayout_ocr_gen)
        self.vBoxLayout.addLayout(self.hBoxLayout_gen)
        self.vBoxLayout.addLayout(self.gridLayout_loc)
        self.vBoxLayout.addLayout(self.hBoxLayout_map)
        self.vBoxLayout.addLayout(self.hBoxLayout_tips)
        
    def update_win_combo(self):
        self.win_combo.clear()
        hwnd_title.clear()
        win32gui.EnumWindows(get_all_hwnd, 0)
        for h, t in hwnd_title.items():
            if t.startswith('梦幻西游 ONLINE'):
                self.win_combo.addItem(str(h)+":"+t)
                
    def getWinText(self):
        win_text = self.win_combo.currentText()
        if win_text == "":
            msg = "没有可用窗口"
            logger.warning(msg)
            self.setTips(msg) 
            self.update_win_combo()
            return None, False
        
        h = win_text.split(':')[0]
        t = win_text.split(':')[1]
        logger.info(f"{h} {t}")
        
        if not win32gui.IsWindowEnabled(h):
            self.setTips("无效窗口")
            self.map_label.clear()
            self.update_win_combo()
            return None, False
    
        return (h, t), True
        
    def setTips(self, tips):
        self.tips_label.setText(f"<font color='red'>{tips}</font>")
        
    def onclick_loc(self, arg):
        self.loc_le.setFocus()
        self.loc_le.setText(f"{arg} ")
        
    def show_developmode(self):
        # 计算主窗口中心位置
        main_window_center = self.father.main_window.LocateCenter()
        print(f"main window location: {main_window_center}")
        x = main_window_center.x() - c.win_width / 2 + 20
        y = main_window_center.y() - 250
        p = QPoint(x, y)
        self.sf_developmode.move(p)
        self.sf_developmode.show()
        
    def on_return_loc_le(self, entered_text, flag_ocr=False):
        self.setTips("")
        # 当用户按下回车时调用
        loc, ok = decode_loc(entered_text)
        if not ok:
            self.map_label.clear()
            self.setTips("错误格式，或不支持该地图")
            return
        logger.info(f"loc: {loc}")
        m = loc[0][0]
        x = loc[0][1]
        y = loc[0][2]
        map_img_path = f"{c.map_dir_path}/{m}.jpg"
        logger.info(f"loc: {map_img_path} x: {x} y: {y}")
        
        if self.prec_cb.isChecked():
            qImage, ok = draw_map_prec(map_img_path, loc[0], loc[1], loc[2], flag_ocr)
            if not ok:
                self.map_label.clear()
                self.setTips("程序异常,避免程序放在中文路径")
                return
        else:
            qImage, ok = draw_map(map_img_path, loc[1], loc[2], flag_ocr)
            if not ok:
                self.map_label.clear()
                self.setTips("程序异常,避免程序放在中文路径")
                return
        
        if not ok:
            self.map_label.clear()
            self.setTips("资源缺失")
            return
        # 从 QImage 创建 QPixmap
        pixmap = QPixmap.fromImage(qImage)
        
        # pixmap = QPixmap(map_img_path)  
        scaled_pixmap = pixmap.scaled(415, 380, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        width = scaled_pixmap.width()
        height = scaled_pixmap.height()
        logger.info(f"w: {width}, h: {height}")
        self.map_label.setPixmap(scaled_pixmap)
        
    def onclick_recogize(self):
        if c.URL_QA == "":
            self.setTips("请先设置后台 ip 和 port")
            return
        
        self.setTips("")
        if not u.signin_flag:
            msg = "仅登录用户可用"
            self.setTips(msg)
            logger.warning(msg) 
            return
        
        ht, ok = self.getWinText()
        if not ok:
            return
        
        h = ht[0]
        t = ht[1]
        ts = time_str()
        
        # img_hwnd = get_screenshot_image(int(h))
        img_hwnd = get_mss_screenshot_image(int(h))
        
        logger.info(f"shot size {img_hwnd.size}")
        
        if c.develop_mode:
            self.setTips("开发者模式，用于图片截取校准，正常使用请退出该模式！")
            file_img = f"{c.shot_dir_path}/dm_{h}_{ts}.jpg"
            img_hwnd.save(file_img)
            logger.info(f'img_desktop save to -> {os.path.abspath(file_img)}')
            self.sf_developmode.UpdateImage(file_img, c.coord_shot_rect.copy())
            self.show_developmode()
            return
        
        crop_box = (c.coord_shot_rect[0], c.coord_shot_rect[1], c.coord_shot_rect[2], c.coord_shot_rect[3])
        img_hwnd = img_hwnd.crop(crop_box)
        
        
        file_img = f"{c.shot_dir_path}/{h}_{t}_crop_{ts}.jpg"
        img_hwnd.save(file_img)
        logger.info(f'img_desktop save to -> {os.path.abspath(file_img)}')
        
        # file_img = os.path.join(c.shot_dir_path, r'1708498624.png')
        
        coord, ok = maocr.mhxy_coord_ocr(file_img, u.signin_token)
        delete_file(file_img)
        if ok:
            loc = coord[0]
            ocrleftcount = coord[1]
            msg = coord[2]
            c.annc_server = coord[3]
            c.annc_sponsor = coord[4]
            if msg == "":
                self.loc_ocr_le.setText(loc)
                self.on_return_loc_le(loc, True)
            else:
                self.setTips(msg)
                self.map_label.clear()
            self.recognize_btn.setText(f"RE({ocrleftcount})")
        else:
            self.map_label.clear()
            self.setTips("识别失败")
        


class CoordInterface(SingleDirectionScrollArea):

    def __init__(self, parent=None):
        super().__init__(parent=None)
        self.main_window = parent
        self.view = QWidget(self)

        self.vBoxLayout = QVBoxLayout(self.view)
        self.coordCard = CoordInfoCard(self)
        self.coordCard.setMaximumWidth(c.card_width)
        self.setWidget(self.view)
        self.setWidgetResizable(True)
        self.setObjectName('CoordInterface')

        self.vBoxLayout.setSpacing(10)
        self.vBoxLayout.setContentsMargins(0, 0, 15, 0)
        self.vBoxLayout.addWidget(self.coordCard, 0, Qt.AlignTop)

        self.setStyleSheet("QScrollArea {border: none; background:transparent}")
        self.view.setStyleSheet('QWidget {background:transparent}')
        
    def show(self):
        logger.info("show CoordInterface")
        